package com.kunda.netty.protocol;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;

import com.google.protobuf.GeneratedMessage;
import com.google.protobuf.Parser;
import com.kunda.netty.protocol.RHMS.MsgType;
import com.kunda.netty.util.MapUtil;
import com.kunda.netty.util.MessageUtil;

public class RequestDispatcherHandler extends ChannelHandlerAdapter {
	private ConcurrentHashMap<MsgType, Parser<?>> parserMap = new ConcurrentHashMap<MsgType, Parser<?>>();

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg)
			throws Exception {
		
		ByteBuf buf = (ByteBuf)msg;
		
		//get request message
		int msgCode = buf.readInt();
		MsgType msgType = MsgType.valueOf(msgCode);
		Parser<?> parser = parserMap.get(msgType);
		if(parser == null){
			parser = MessageUtil.parseMessageParse(msgType);
			parserMap.put(msgType, parser);
		}
		byte[] protobufBytes = new byte[buf.readableBytes()];
		buf.readBytes(protobufBytes);
		GeneratedMessage requestMessage = (GeneratedMessage)parser.parseFrom(protobufBytes);
		
		Method handleMethod = MapUtil.methodMap.get(msgType);
		Object handleObject = MapUtil.handlerMap.get(msgType);
		GeneratedMessage response  = (GeneratedMessage)handleMethod.invoke(handleObject,requestMessage);
		//do service
		/*RequestService service = (RequestService)MapUtil.serviceMap.get(msgType.name());
		GeneratedMessage response = service.doService(requestMessage);*/
		System.out.println(response);
		
		//add msgType
		int responseType = MessageUtil.parseMessageType(response);
		byte[] bytes = response.toByteArray();
		ByteBuf responseMessage = Unpooled.buffer(bytes.length+4);
		responseMessage.writeInt(responseType)
					   .writeBytes(bytes);
		
		ctx.writeAndFlush(responseMessage);
	}

}
